package com.stylefeng.guns.modular.model.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.stylefeng.guns.core.common.Result;
import com.stylefeng.guns.core.wxutils.login.*;
//import com.stylefeng.guns.modular.foodmall.model.Weixinuserinfo;
//import com.stylefeng.guns.modular.foodmall.service.IWeixinuserinfoService;
import com.stylefeng.guns.modular.model.service.IWeixininfoService;
import com.stylefeng.guns.modular.system.model.Weixininfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author 杜长青
 * @description 微信授权 回调
 * @date 2018/8/1 下午6:20
 **/

@Controller
@RequestMapping("/wechat")
public class WxAuthorController {
    @Autowired
    private IWeixininfoService weixinuserinfoService;

    /**
     * 获得小程序的openID
     *
     * @param userCode
     * @return
     */
    @RequestMapping("/getOpenID")
    @ResponseBody
    public Object getOpenID(@RequestParam("userCode") String userCode) {
        try {
            String param = "appid=" + Configure.APP_ID
                    + "&secret=" + Configure.APP_SECRET
                    + "&js_code=" + userCode
                    + "&grant_type=authorization_code";

            return Result.success("success", HttpRequest.sendGet("https://api.weixin.qq.com/sns/jscode2session", param));
        } catch (Exception e) {
            e.printStackTrace();
            return Result.error("获得openID异常");
        }
    }

    /**
     * @author 杜长青
     * @description 解密用户敏感数据
     * @date 2018/8/2 下午12:18
     * @param encryptedData 加密后的数据
     * @param iv 加密算法的初始向量
     * @param code 用户允许登录后，回调内容会带上 code（有效期五分钟），开发者需要将 code 发送到开发者服务器后台，使用code 换取 session_key api，将 code 换成 openid 和 session_key
     * @return
     */
    @RequestMapping("/decodeUserInfo")
    @ResponseBody
    public Map decodeUserInfo(@RequestParam("encryptedData") String encryptedData,
                              @RequestParam("iv") String iv, @RequestParam("code") String code) {

        Map map = new HashMap();

        // 登录凭证不能为空
        if (code == null || code.length() == 0) {
            map.put("status", 0);
            map.put("msg", "code 不能为空");
            return map;
        }

        //////////////// 1、向微信服务器 使用登录凭证 code 获取 session_key 和 openid
        //////////////// ////////////////
        // 请求参数
        String params = "appid=" + Configure.APP_ID + "&secret=" + Configure.APP_SECRET + "&js_code=" + code + "&grant_type=authorization_code";
        // 发送请求
        String sr = HttpRequest.sendGet("https://api.weixin.qq.com/sns/jscode2session", params);
        // 解析相应内容（转换成json对象）
        JSONObject json = JSONObject.parseObject(sr);
        // 获取会话密钥（session_key）
        String session_key = json.get("session_key").toString();
        // 用户的唯一标识（openid）
        String openid = (String) json.get("openid");

        //////////////// 2、对encryptedData加密数据进行AES解密 ////////////////
        try {
//            String result = AesCbcUtil.decrypt(encryptedData, session_key, iv, "UTF-8");
            String result = WXUtils.getUserInfo(encryptedData, session_key, iv);
            if (null != result && result.length() > 0) {
                map.put("status", 1);
                map.put("msg", "解密成功");

                JSONObject userInfoJSON = JSONObject.parseObject(result);

                Weixininfo user = new Weixininfo();
                user.setWeixinnickname(userInfoJSON.getString("nickName"));
                user.setHeadimgurl(userInfoJSON.getString("avatarUrl"));
                user.setOpenid(userInfoJSON.getString("openId"));
                user.setUnionid(userInfoJSON.getString("unionId"));
                user.setGender(userInfoJSON.getString("gender"));
                user.setCity(userInfoJSON.getString("city"));
                user.setProvince(userInfoJSON.getString("province"));
                user.setCountry(userInfoJSON.getString("country"));

                Weixininfo oldUser = new Weixininfo();
                oldUser.setUnionid(user.getUnionid());
                oldUser = weixinuserinfoService.selectOne(new EntityWrapper<>(oldUser));

                if(oldUser == null){
                    user.setLatesttime(new Date());
//                    user.setModificationtime(new Date());
                    weixinuserinfoService.insert(user);
                }else{
                    user.setLatesttime(new Date());
                    user.setId(oldUser.getId());
                    weixinuserinfoService.updateById(user);
                }
                map.put("userInfo", user);
            } else {
                map.put("status", 0);
                map.put("msg", "解密失败");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 获得小程序accesstoken
     * @param userCode
     * @return
     */
    @RequestMapping("/getAccessToken")
    @ResponseBody
    public Object getAccessToken(@RequestParam("userCode") String userCode) {
//        try {
//            String accessToken = AccessTokenUtils.getAccessToken(appId, appSecret);
//            return Result.success("system.success", accessToken);
//        } catch (Exception e) {
//            e.printStackTrace();
//            return Result.error("system.error");
//        }
        return null;
    }

    /**
     * 发起微信登录
     *
     * @param request
     * @param response
     * @throws IOException
     */
    @RequestMapping("/login")
    public void login(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String callback = request.getParameter("callback");
        if (StringUtils.isNotBlank(callback)) {
            request.getSession().setAttribute("callback", callback);
        }
        StringBuilder url = new StringBuilder("https://open.weixin.qq.com/connect/oauth2/authorize?");
        url.append("appid=");
        url.append(Configure.APP_ID);
        url.append("&redirect_uri=");
        url.append(URLEncoder.encode(Configure.LOGIN_CALLBACK_URL));
        url.append("&response_type=code&scope=snsapi_userinfo&state=" + callback + "#wechat_redirect");
        response.sendRedirect(url.toString());
    }

    /**
     * 用户授权后微信回调地址
     */
    @RequestMapping("/callback")
    public void getUserInfo(@RequestParam("code") String code, @RequestParam("state") String state,
                            HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        System.out.println("开始到了微信回调");
        JSONObject jsonObject = null;//处理微信返回json数据
        String openid = "";//微信用户openid
        String access_token = "";//授权码
        String resultStr = "";//接口返回字符
        String requesUrl = Configure.WX_GET_ACCESS_URL;//获取openid地址
        String userinfoUrl = Configure.WX_GET_USER_INFO_URL;//拉取用户信息地址
        try {
            if (!StringUtils.isBlank(code) && !StringUtils.isBlank(requesUrl)) {//开始获取用户openid
                requesUrl = requesUrl.replace("APP_ID", Configure.APP_ID).replace("APP_SECRET", Configure.APP_SECRET).replace("USE_CODE", code);
                resultStr = HttpsUtil.httpsRequest(requesUrl, "GET", null);//调用获取openid接口
                if (!StringUtils.isBlank(resultStr) && resultStr.indexOf("openid") > 0) {
                    jsonObject = JSONObject.parseObject(resultStr);
                    openid = jsonObject.get("openid").toString();
                    System.out.println("userService.getOneByOpenid" + "...." + openid);
                    Weixininfo user = new Weixininfo();
                    user.setOpenid(openid);
                    user = weixinuserinfoService.selectOne(new EntityWrapper<>(user));
                    if (user == null) {
                        System.out.println("user==null");
                        if (resultStr.indexOf("access_token") > 0) {
                            access_token = jsonObject.get("access_token").toString();
                        }
                        userinfoUrl = userinfoUrl.replace("ACCESS_TOKEN", access_token).replace("OPEN_ID", openid);
                        resultStr = HttpsUtil.httpsRequest(userinfoUrl, "GET", null);//拉取用户信息
                        if (!StringUtils.isBlank(resultStr) && resultStr.indexOf("openid") > 0) {//判断返回值是否含有openid
                            jsonObject = JSONObject.parseObject(resultStr);
                            //这里可以用oppenid获取数据库t_user表里的user信息判断是否已经存在该user
                            user = this.getWxUser(jsonObject);
                            //开始插入用户信息
                            String nickName = StringFormat.toSubString(user.getWeixinnickname());
                            if ("".equals(nickName)) {
                                user.setWeixinnickname("...");
                            } else {
                                user.setWeixinnickname(nickName);
                            }
                            user.setLatesttime(new Date());
                            weixinuserinfoService.insert(user);
                            System.out.println("userService.insertSelective" + user);
                        }
                    }
                    // SessionUtil.setUser(request, user);//
                    if (!state.contains("loginCode")) {
                        String loginCode = UUID.randomUUID().toString();
                        state += "&loginCode=" + loginCode;
                    }
                    System.out.println("开始到了微信回调");
                } else {//授权失败或者网络异常
                    System.out.println("授权失败,返回code为：" + code + "获取openid地址:" + requesUrl);
                }
            } else {
                //获取code失败 用户不同意授权，以游客身份进入
                System.out.println("获取code失败....");
            }
        } catch (Exception e) {
            System.out.println("发生异常：" + e.getMessage());
        }
        System.out.println("微信回调结束");
        String host = state.substring(0, state.indexOf("/", "http://".length()));
        String url = host + "/page/wechat-login.html?url=" + state;
        response.sendRedirect(url);
        return;
    }
    public Weixininfo getWxUser(JSONObject json) {
        Weixininfo user = null;
        String str = json.toString();
        if (str == null || StringUtils.isBlank(str)) {
            return null;
        } else {
            user = new Weixininfo();
            if (str.indexOf("sex") > 0)
                user.setGender(json.get("sex").toString());
            if (str.indexOf("nickname") > 0)
                user.setWeixinnickname(json.get("nickname").toString());
            if (str.indexOf("province") > 0)
                user.setProvince(json.get("province").toString());
            if (str.indexOf("openid") > 0)
                user.setOpenid(json.get("openid").toString());
            if (str.indexOf("headimgurl") > 0)
                user.setHeadimgurl(json.get("headimgurl").toString());
            if (str.indexOf("country") > 0)
                user.setCountry(json.get("country").toString());
            if (str.indexOf("city") > 0)
                user.setCity(json.get("city").toString());
        }
        return user;
    }

}